home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 25 / AACD 25.iso / AACD / Utilities / BasiliskII / src / uae_cpu / newcpu.h < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-20  |  7.4 KB  |  312 lines

  1.  /*
  2.   * UAE - The Un*x Amiga Emulator
  3.   *
  4.   * MC68000 emulation
  5.   *
  6.   * Copyright 1995 Bernd Schmidt
  7.   */
  8.  
  9. #ifndef NEWCPU_H
  10. #define NEWCPU_H
  11.  
  12. #define SPCFLAG_STOP 2
  13. #define SPCFLAG_DISK 4
  14. #define SPCFLAG_INT  8
  15. #define SPCFLAG_BRK  16
  16. #define SPCFLAG_EXTRA_CYCLES 32
  17. #define SPCFLAG_TRACE 64
  18. #define SPCFLAG_DOTRACE 128
  19. #define SPCFLAG_DOINT 256
  20. #define SPCFLAG_BLTNASTY 512
  21. #define SPCFLAG_EXEC 1024
  22. #define SPCFLAG_MODE_CHANGE 8192
  23.  
  24. #ifndef SET_CFLG
  25.  
  26. #define SET_CFLG(x) (CFLG = (x))
  27. #define SET_NFLG(x) (NFLG = (x))
  28. #define SET_VFLG(x) (VFLG = (x))
  29. #define SET_ZFLG(x) (ZFLG = (x))
  30. #define SET_XFLG(x) (XFLG = (x))
  31.  
  32. #define GET_CFLG CFLG
  33. #define GET_NFLG NFLG
  34. #define GET_VFLG VFLG
  35. #define GET_ZFLG ZFLG
  36. #define GET_XFLG XFLG
  37.  
  38. #define CLEAR_CZNV do { \
  39.  SET_CFLG (0); \
  40.  SET_ZFLG (0); \
  41.  SET_NFLG (0); \
  42.  SET_VFLG (0); \
  43. } while (0)
  44.  
  45. #define COPY_CARRY (SET_XFLG (GET_CFLG))
  46. #endif
  47.  
  48. extern int areg_byteinc[];
  49. extern int imm8_table[];
  50.  
  51. extern int movem_index1[256];
  52. extern int movem_index2[256];
  53. extern int movem_next[256];
  54.  
  55. extern int fpp_movem_index1[256];
  56. extern int fpp_movem_index2[256];
  57. extern int fpp_movem_next[256];
  58.  
  59. extern int broken_in;
  60.  
  61. typedef void REGPARAM2 cpuop_func (uae_u32) REGPARAM;
  62.  
  63. struct cputbl {
  64.     cpuop_func *handler;
  65.     int specific;
  66.     uae_u16 opcode;
  67. };
  68.  
  69. extern void REGPARAM2 op_illg (uae_u32) REGPARAM;
  70.  
  71. typedef char flagtype;
  72.  
  73. extern struct regstruct
  74. {
  75.     uae_u32 regs[16];
  76.     uaecptr  usp,isp,msp;
  77.     uae_u16 sr;
  78.     flagtype t1;
  79.     flagtype t0;
  80.     flagtype s;
  81.     flagtype m;
  82.     flagtype x;
  83.     flagtype stopped;
  84.     int intmask;
  85.  
  86.     uae_u32 pc;
  87.     uae_u8 *pc_p;
  88.     uae_u8 *pc_oldp;
  89.  
  90.     uae_u32 vbr,sfc,dfc;
  91.  
  92.     double fp[8];
  93.     uae_u32 fpcr,fpsr,fpiar;
  94.  
  95.     uae_u32 spcflags;
  96.     uae_u32 kick_mask;
  97.  
  98.     /* Fellow sources say this is 4 longwords. That's impossible. It needs
  99.      * to be at least a longword. The HRM has some cryptic comment about two
  100.      * instructions being on the same longword boundary.
  101.      * The way this is implemented now seems like a good compromise.
  102.      */
  103.     uae_u32 prefetch;
  104. } regs, lastint_regs;
  105.  
  106. #define m68k_dreg(r,num) ((r).regs[(num)])
  107. #define m68k_areg(r,num) (((r).regs + 8)[(num)])
  108.  
  109. #define get_ibyte(o) do_get_mem_byte((uae_u8 *)(regs.pc_p + (o) + 1))
  110. #define get_iword(o) do_get_mem_word((uae_u16 *)(regs.pc_p + (o)))
  111. #define get_ilong(o) do_get_mem_long((uae_u32 *)(regs.pc_p + (o)))
  112.  
  113. #ifdef HAVE_GET_WORD_UNSWAPPED
  114. #define GET_OPCODE (do_get_mem_word_unswapped (regs.pc_p))
  115. #else
  116. #define GET_OPCODE (get_iword (0))
  117. #endif
  118.  
  119. static __inline__ uae_u32 get_ibyte_prefetch (uae_s32 o)
  120. {
  121.     if (o > 3 || o < 0)
  122.     return do_get_mem_byte((uae_u8 *)(regs.pc_p + o + 1));
  123.  
  124.     return do_get_mem_byte((uae_u8 *)(((uae_u8 *)®s.prefetch) + o + 1));
  125. }
  126. static __inline__ uae_u32 get_iword_prefetch (uae_s32 o)
  127. {
  128.     if (o > 3 || o < 0)
  129.     return do_get_mem_word((uae_u16 *)(regs.pc_p + o));
  130.  
  131.     return do_get_mem_word((uae_u16 *)(((uae_u8 *)®s.prefetch) + o));
  132. }
  133. static __inline__ uae_u32 get_ilong_prefetch (uae_s32 o)
  134. {
  135.     if (o > 3 || o < 0)
  136.     return do_get_mem_long((uae_u32 *)(regs.pc_p + o));
  137.     if (o == 0)
  138.     return do_get_mem_long(®s.prefetch);
  139.     return (do_get_mem_word (((uae_u16 *)®s.prefetch) + 1) << 16) | do_get_mem_word ((uae_u16 *)(regs.pc_p + 4));
  140. }
  141.  
  142. #define m68k_incpc(o) (regs.pc_p += (o))
  143.  
  144. static __inline__ void fill_prefetch_0 (void)
  145. {
  146. #if USE_PREFETCH_BUFFER
  147.     uae_u32 r;
  148. #ifdef UNALIGNED_PROFITABLE
  149.     r = *(uae_u32 *)regs.pc_p;
  150.     regs.prefetch = r;
  151. #else
  152.     r = do_get_mem_long ((uae_u32 *)regs.pc_p);
  153.     do_put_mem_long (®s.prefetch, r);
  154. #endif
  155. #endif
  156. }
  157.  
  158. #if 0
  159. static __inline__ void fill_prefetch_2 (void)
  160. {
  161.     uae_u32 r = do_get_mem_long (®s.prefetch) << 16;
  162.     uae_u32 r2 = do_get_mem_word (((uae_u16 *)regs.pc_p) + 1);
  163.     r |= r2;
  164.     do_put_mem_long (®s.prefetch, r);
  165. }
  166. #else
  167. #define fill_prefetch_2 fill_prefetch_0
  168. #endif
  169.  
  170. /* These are only used by the 68020/68881 code, and therefore don't
  171.  * need to handle prefetch.  */
  172. static __inline__ uae_u32 next_ibyte (void)
  173. {
  174.     uae_u32 r = get_ibyte (0);
  175.     m68k_incpc (2);
  176.     return r;
  177. }
  178.  
  179. static __inline__ uae_u32 next_iword (void)
  180. {
  181.     uae_u32 r = get_iword (0);
  182.     m68k_incpc (2);
  183.     return r;
  184. }
  185.  
  186. static __inline__ uae_u32 next_ilong (void)
  187. {
  188.     uae_u32 r = get_ilong (0);
  189.     m68k_incpc (4);
  190.     return r;
  191. }
  192.  
  193. #if !defined USE_COMPILER
  194. static __inline__ void m68k_setpc (uaecptr newpc)
  195. {
  196. #if REAL_ADDRESSING || DIRECT_ADDRESSING
  197.     regs.pc_p = get_real_address(newpc);
  198. #else
  199.     regs.pc_p = regs.pc_oldp = get_real_address(newpc);
  200.     regs.pc = newpc;
  201. #endif
  202. }
  203. #else
  204. extern void m68k_setpc (uaecptr newpc);
  205. #endif
  206.  
  207. static __inline__ uaecptr m68k_getpc (void)
  208. {
  209. #if REAL_ADDRESSING || DIRECT_ADDRESSING
  210.     return get_virtual_address(regs.pc_p);
  211. #else
  212.     return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp);
  213. #endif
  214. }
  215.  
  216. #ifdef USE_COMPILER
  217. extern void m68k_setpc_fast (uaecptr newpc);
  218. extern void m68k_setpc_bcc (uaecptr newpc);
  219. extern void m68k_setpc_rte (uaecptr newpc);
  220. #else
  221. #define m68k_setpc_fast m68k_setpc
  222. #define m68k_setpc_bcc  m68k_setpc
  223. #define m68k_setpc_rte  m68k_setpc
  224. #endif
  225.  
  226. static __inline__ void m68k_do_rts(void)
  227. {
  228.         m68k_setpc(get_long(m68k_areg(regs, 7)));
  229.             m68k_areg(regs, 7) += 4;
  230. }
  231.  
  232. static __inline__ void m68k_do_bsr(uaecptr oldpc, uae_s32 offset)
  233. {
  234.         m68k_areg(regs, 7) -= 4;
  235.             put_long(m68k_areg(regs, 7), oldpc);
  236.             m68k_incpc(offset);
  237. }
  238.  
  239. static __inline__ void m68k_do_jsr(uaecptr oldpc, uaecptr dest)
  240. {
  241.         m68k_areg(regs, 7) -= 4;
  242.             put_long(m68k_areg(regs, 7), oldpc);
  243.             m68k_setpc(dest);
  244. }
  245.  
  246. static __inline__ void m68k_setstopped (int stop)
  247. {
  248.     regs.stopped = stop;
  249.     if (stop)
  250.     regs.spcflags |= SPCFLAG_STOP;
  251. }
  252.  
  253. extern uae_u32 get_disp_ea_020 (uae_u32 base, uae_u32 dp);
  254. extern uae_u32 get_disp_ea_000 (uae_u32 base, uae_u32 dp);
  255.  
  256. extern uae_s32 ShowEA (int reg, amodes mode, wordsizes size, char *buf);
  257.  
  258. extern void MakeSR (void);
  259. extern void MakeFromSR (void);
  260. extern void Exception (int, uaecptr);
  261. extern void dump_counts (void);
  262. extern void m68k_move2c (int, uae_u32 *);
  263. extern void m68k_movec2 (int, uae_u32 *);
  264. extern void m68k_divl (uae_u32, uae_u32, uae_u16, uaecptr);
  265. extern void m68k_mull (uae_u32, uae_u32, uae_u16);
  266. extern void init_m68k (void);
  267. extern void exit_m68k (void);
  268. extern void m68k_go (int);
  269. extern void m68k_dumpstate (uaecptr *);
  270. extern void m68k_disasm (uaecptr, uaecptr *, int);
  271. extern void m68k_reset (void);
  272. extern void m68k_enter_debugger(void);
  273.  
  274. extern void mmu_op (uae_u32, uae_u16);
  275.  
  276. extern void fpp_opp (uae_u32, uae_u16);
  277. extern void fdbcc_opp (uae_u32, uae_u16);
  278. extern void fscc_opp (uae_u32, uae_u16);
  279. extern void ftrapcc_opp (uae_u32,uaecptr);
  280. extern void fbcc_opp (uae_u32, uaecptr, uae_u32);
  281. extern void fsave_opp (uae_u32);
  282. extern void frestore_opp (uae_u32);
  283.  
  284. extern void fpu_set_integral_fpu (bool is_integral);
  285. extern void fpu_init (void);
  286. extern void fpu_exit (void);
  287. extern void fpu_reset (void);
  288.  
  289. /* Opcode of faulting instruction */
  290. extern uae_u16 last_op_for_exception_3;
  291. /* PC at fault time */
  292. extern uaecptr last_addr_for_exception_3;
  293. /* Address that generated the exception */
  294. extern uaecptr last_fault_for_exception_3;
  295.  
  296. #define CPU_OP_NAME(a) op ## a
  297.  
  298. /* 68020 + 68881 */
  299. extern struct cputbl op_smalltbl_0[];
  300. /* 68020 */
  301. extern struct cputbl op_smalltbl_1[];
  302. /* 68010 */
  303. extern struct cputbl op_smalltbl_2[];
  304. /* 68000 */
  305. extern struct cputbl op_smalltbl_3[];
  306. /* 68000 slow but compatible.  */
  307. extern struct cputbl op_smalltbl_4[];
  308.  
  309. extern cpuop_func *cpufunctbl[65536] ASM_SYM_FOR_FUNC ("cpufunctbl");
  310.  
  311. #endif /* NEWCPU_H */
  312.